﻿using RndMaterialDisposalService.Attrbutes;
using RndMaterialDisposalService.Models;
using RndMaterialDisposalService.Models.Entitys;
using RndMaterialDisposalService.Models.RequestModel;
using RndMaterialDisposalService.Repository;
using RndMaterialDisposalService.Services.Interface;
using AutoMapper;
using Masuit.Tools;
using Masuit.Tools.Core.AspNetCore;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.Json;

namespace RndMaterialDisposalService.Services.VehicleDispatchService
{
    /// <summary>
    /// 
    /// </summary>
    [NAutowired]
    public class InternalVehicleService : IInternalVehicleService
    {
        private readonly IMapper mapper;
        private readonly AssetsManagementContext dbContext;
        private readonly WorkflowCommonDataContext commonDataContext;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_dbContext"></param>
        /// <param name="_commonDataContext"></param>
        /// <param name="_mapper"></param>
        public InternalVehicleService(AssetsManagementContext _dbContext, WorkflowCommonDataContext _commonDataContext, IMapper _mapper)
        {
            dbContext = _dbContext;
            commonDataContext = _commonDataContext;
            mapper = _mapper;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="inputReq"></param>
        /// <returns></returns>
        public async Task<(List<InternalVehicleReportDto> list, int count)> GetReportData(InternalVehicleReportDataReq inputReq)
        {
            var list = dbContext.InternalVehicleReport.Where(p => 1 == 1);
            if (!string.IsNullOrEmpty(inputReq.Subject))
            {
                list = list.Where(p => p.Subject.Contains(inputReq.Subject));
            }
            if (!string.IsNullOrEmpty(inputReq.DeptName))
            {
                list = list.Where(p => p.DeptName.Contains(inputReq.DeptName));
            }
            if (!string.IsNullOrEmpty(inputReq.UseCarName))
            {
                list = list.Where(p => p.UseCarName.Contains(inputReq.UseCarName));
            }
            if (!string.IsNullOrEmpty(inputReq.Applicant))
            {
                list = list.Where(p => p.Applicant == inputReq.Applicant);
            }
            if (inputReq.UseCarStartDate!=null && inputReq.UseCarEndDate!=null)
            {
                list = list.Where(p => p.UseCarDate >= inputReq.UseCarStartDate && p.UseCarDate < inputReq.UseCarEndDate);
            }
            if (inputReq.ApplicationStartDate != null && inputReq.ApplicationEndDate != null )
            {
                list = list.Where(p => p.ApplicantDate >= inputReq.ApplicationStartDate && p.ApplicantDate < inputReq.ApplicationEndDate);
            }

            //处理当前节点名称
            var procinstIdList = list.Select(p => $"{p.ProcInstId}".Trim()).ToList();
            var result2 = await commonDataContext.ApplicationData.Where(p => procinstIdList.Contains(p.ProcInstId!.Trim())).ToListAsync();
            list.ForEach(item =>
            {
                var procItem = result2.Where(p => p.ProcInstId!.Trim() == item.ProcInstId!.Trim());
                if (procItem.Any())
                {
                    item.ActivityName = procItem.First().CurrentStatus?.Trim();
                }
            });

            var newlist = await list.ToListAsync();
            if (!string.IsNullOrEmpty(inputReq.ActivityName))
            {
                newlist = newlist.Where(p => p.ActivityName == inputReq.ActivityName).ToList();
            }


            //普通用户报表
            if (!string.IsNullOrEmpty(inputReq.CurrentUser))
            {
                var folioList = await commonDataContext.ApplicationApproveData
                    .Where(p => "内部人员用车申请表".Equals(p.WorkflowName!.Trim()) && inputReq.CurrentUser == p.ApproverName!.Trim())
                    .Select(p => p.ApplicationNumber!.Trim())
                    .Distinct()
                    .ToListAsync();
                newlist = newlist.Where(p => folioList.Contains(p.Folio!.Trim())).ToList();
            }

            var count = newlist.Count();
            var data = newlist.OrderByDescending(p => p.UseCarDate)
                .Skip((inputReq.PageIndex - 1) * inputReq.PageSize)
                .Take(inputReq.PageSize).ToList();
            return (data, count);
        }

        /// <summary>
        /// 保存报表数据
        /// </summary>
        /// <param name="reportModel"></param>
        /// <returns></returns>
        public async Task<int> SaveReportData(InternalVehicleReportDto reportModel)
        {
            dbContext.InternalVehicleReport.AddOrUpdate(p => p.ProcInstId, reportModel);
            return await dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="formId"></param>
        /// <returns></returns>
        public async Task<ConfirmationExpenseDto> GetConfirmationExpenseFormData(string formId)
        {
            var result = await dbContext.ConfirmationExpense.FirstOrDefaultAsync(p => p.FormId == formId);
            if (result == null)
            {
                var data = await commonDataContext.ApplicationData.FirstOrDefaultAsync(p => p.ID.ToString() == formId);
                if (!string.IsNullOrEmpty(data!.FormData))
                {
                    var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
                    var formdata = System.Text.Json.JsonSerializer.Deserialize<InternalVehicleFormDataReq>(data.FormData!, options);
                    result = mapper.Map<ConfirmationExpenseDto>(formdata);
                }
            }
            return result ?? new ConfirmationExpenseDto();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="formData"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> SaveConfirmationExpenseFormData(ConfirmationExpenseDto formData)
        {
            dbContext.ConfirmationExpense.AddOrUpdate((p) => p.Subject, formData);
            return await dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="inputReq"></param>
        /// <returns></returns>
        public async Task<(List<ConfirmationExpenseDto> list, int count)> ConfirmationExpenseReportData(ConfirmationExpenseReportDataReq inputReq)
        {
            var list = dbContext.ConfirmationExpense.Where(p => 1 == 1);
            if (!string.IsNullOrEmpty(inputReq.DeptName))
            {
                list = list.Where(p => !string.IsNullOrEmpty(p.UseDeptNameCode) && p.UseDeptNameCode.Contains(inputReq.DeptName!));
            }
            if (!string.IsNullOrEmpty(inputReq.ProcFolio))
            {
                list = list.Where(p => !string.IsNullOrEmpty(p.ProcFolio) && p.ProcFolio.Contains(inputReq.ProcFolio!));
            }
            if (!string.IsNullOrEmpty(inputReq.ProviderName))
            {
                list = list.Where(p => !string.IsNullOrEmpty(p.ProviderName) && p.ProviderName.Contains(inputReq.ProviderName!));
            }
            if (!string.IsNullOrEmpty(inputReq.UseCarName))
            {
                list = list.Where(p => !string.IsNullOrEmpty(p.UseCarName) && p.UseCarName.Contains(inputReq.UseCarName!));
            }
            var count = await list.CountAsync();
            var data = await list.OrderByDescending(p => p.ConfirmDate).Skip((inputReq.PageIndex - 1) * inputReq.PageSize).Take(inputReq.PageSize).ToListAsync();
            return (data, count);
        }
    }
}
